<?php

namespace App\Http\Controllers\Wechat;

use App\Http\Controllers\QrCodeController;
use App\Models\AppInviteCodeBehavior;
use App\Models\Banner;
use App\Models\UserAddress;
use App\Models\Goods;
use App\Models\GoodsAddress;
use App\Models\GoodsImg;
use App\Models\GoodsOrder;
use App\Models\GoodsOrderAddress;
use App\Models\GoodsType;
use App\Models\UserLibraryInfo;
use App\Validate\GoodsValidate;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

/**
 * 商品管理
 */
class GoodsController extends CommonController
{

    public $model = null;
    public $orderModel = null;
    public $validate = null;

    public function __construct()
    {
        parent::__construct();

        $this->model = new Goods();
        $this->orderModel = new GoodsOrder();
        $this->validate = new GoodsValidate();
    }

    /**
     * 类型(用于下拉框选择)
     */
    public function filterList()
    {
        $goodsTypeModel = new GoodsType();
        $condition[] = ['is_del', '=', 1];

        return $goodsTypeModel->getFilterList(['id', 'type_name'], $condition);
    }


    /**
     * 根据商品类型  获取商品列表
     * @param token    用户    可选
     * @param type_id  全部 为 0；
     * @param page  页数 默认为 1
     * @param limit  限制条数  默认 10 条
     * @param keywords  检索条件
     */
    public function lists()
    {
        $page = $this->request->page ? intval($this->request->page) : 1;
        $limit = $this->request->limit ? intval($this->request->limit) : 10;
        $type_id = $this->request->type_id;
        $keywords = $this->request->keywords;
        $user_id = $this->request->user_info['id'];

        $res = $this->model->lists($type_id, $user_id, $keywords, $limit);


        //增加行为分析
        $appInviteCodeBehaviorModel = new  \App\Models\AppInviteCodeBehavior();
        $appInviteCodeBehaviorModel->add(11);

        if (!empty($res['data'])) {
            $res = $this->disPageData($res);
            //获取banner图片
            $res['banner'] = Banner::getBannerList(2); //banenr图片
            return $this->returnApi(200, '获取成功', true, $res);
        }
        return $this->returnApi(203, '暂无数据');
    }


    /**
     * 商品详情
     * @param token    可选
     * @param id  商品id
     */
    public function detail()
    {
        $this->orderModel->checkOrderStatus(); //处理已过期的订单
        $this->orderModel->checkNoPayOrder(); //获取未支付的订单，判断是否过期，修改状态
        //增加验证场景进行验证
        if (!$this->validate->scene('web_detail')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        $user_id = $this->request->user_info['id'];


        $res = $this->model->where('is_del', 1)->where('is_play', 1)->find($this->request->id);
        if (empty($res)) {
            return $this->returnApi(203, '暂无数据');
        }
        $res = $res->toArray();

        $res['surplus_number'] = $res['number'] - $res['has_number'];
        $goodsTypeModel = new GoodsType();
        $res['tag'][] = $goodsTypeModel->where('id', $res['type_id'])->value('type_name');
        $res['img_all'] = GoodsImg::select('img', 'thumb_img')->where('goods_id', $res['id'])->get();
        $res['user_times'] = 0;

        /*$res['img_all'] = [];
        foreach ($img_temp as $key => $value) {
           $temp_array = explode('|',$value['img']);
            foreach ($temp_array as $img_key => $img_value) {
                $temp['img'] = $value['img'];
                $temp['thumb_img'] = $value['thumb_img'];
                $res['img_all'][] = $temp;
           // }
        }*/

        if ($res['send_way'] == 1) {
            $res['tag'][] = '仅支持自提';
        } elseif ($res['send_way'] == 2) {
            $res['tag'][] = '仅支持邮递';
        } else {
            $res['tag'][] = '支持自提';
            $res['tag'][] = '邮递配送';
        }
        $res['tag'][] = $res['times'] == 1 ? '一次性兑换' : '多次兑换';

        //是否可以兑换
        if ($res['surplus_number'] <= 0) {
            $res['is_convert'] = false;
        } elseif ($res['start_time'] > date('Y-m-d H:i:s') ||  $res['end_time'] < date('Y-m-d H:i:s')) {
            $res['is_convert'] = false;
        } else {
            if (!empty($user_id)) {
                $times = $this->orderModel->getConversionNumber($user_id, $this->request->id);
                $res['user_times'] = $times;
                $res['is_convert'] = $res['times'] === 0 || ($res['times'] - $times > 0) ? true : false;
                //获取用户地址
            } else {
                $res['is_convert'] = true;
            }
        }
        //获取用户收货地址
        if (!empty($user_id)) {
            $addressModelObj = new UserAddress();
            $default_address = $addressModelObj->getDefaultAddress($user_id);
            if ($default_address) {
                $res['address'] = 1;
                $res['default_address'] = $default_address;
            } else {
                $address = $addressModelObj->getAddress($user_id);
                $res['address'] = $address ? 2 : 3; //2有地址，但是没默认地址，3没地址
                $res['default_address'] = [];
            }
        } else {
            $res['is_convert'] = true;
            $res['address'] = 3; //3没地址
            $res['default_address'] = [];
        }

        //获取自提地址
        if ($res['send_way'] == 1 || $res['send_way'] == 3) {
            $pick_address = GoodsAddress::select('province', 'city', 'district', 'street', 'address', 'tel', 'contacts')->first();
            if (empty($pick_address)) {
                $pick_address = [];
            }

            //单个设置存在，覆盖掉总配置
            if ($res['tel']) {
                $pick_address['tel'] = $res['tel'];
            }
            if ($res['contacts']) {
                $pick_address['contacts'] = $res['contacts'];
            }
            $res['pick_address'] = $pick_address;
        }


        $res['lib_name'] = config('other.lib_name');

        unset($res['tel'], $res['contacts']);
        return $this->returnApi(200, '获取成功', true, $res);
    }
    /**
     * 商品兑换 生成预支付订单
     * @param $token token 必选
     * @param $id 商品id
     * @param $send_way 1 自提 2 邮递
     * @param $address_id 邮递必须要传 地址id
     */
    public function goodsConversion()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('web_goods_conversion')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $user_id = $this->request->user_info['id'];
        $account_id = $this->request->user_info['account_id'];

        $address_id = $this->request->address_id;
        $goods_id = $this->request->id;
        $send_way = $this->request->send_way;

        //限制用户多次点击
        $key = md5('goods_conversion-' . $user_id . '-' . $goods_id . '-' . request()->ip());
        $oldKey =  Cache::get($key); //没有缓存返回false
        if ($oldKey) {
            return $this->returnApi(201, "您操作的太频繁了，请稍后重试");
        } else {
            Cache::put($key, 1, 3);
        }

        if ($send_way == 2 && empty($address_id)) {
            return $this->returnApi(202, '邮递地址不能为空');
        }
        $goods = $this->model->where('is_del', 1)->where('is_play', 1)->find($goods_id);

        if (!$goods) {
            return $this->returnApi(202, '无效参数');
        }

        if ($goods->is_play != 1) {
            return $this->returnApi(202, '该商品已下架');
        }

        $times = $this->orderModel->getConversionNumber($user_id, $this->request->id);
        if ($goods->times !== 0 && ($goods->times -  $times) == 0) {
            $has_pay_order = $this->orderModel->where('user_id', $user_id)->where('goods_id', $goods_id)->where('is_pay', 1)->first();
            if ($has_pay_order) {
                return $this->returnApi(202, '存在未支付订单,请直接前往个人中心-兑换历史进行支付');
            }
            return $this->returnApi(202, '此商品已达到重复兑换次数限制,不能再进行兑换');
        }

        DB::beginTransaction();
        try {
            $goods_info = $this->model->lockForUpdate()->find($goods_id);
            $user_library_info = UserLibraryInfo::find($account_id);
            if (empty($user_library_info)) {
                throw new Exception('读者信息获取失败');
            }
            if ($user_library_info->score < $goods_info->score) {
                throw new Exception('积分不足，兑换失败');
            }
            if ($goods_info->number <= $goods_info->has_number) {
                throw new Exception('商品已兑换完毕');
            }
            if ($goods_info->start_time > date('Y-m-d H:i:s')) {
                throw new Exception('兑换时间未开始');
            }
            if ($goods_info->end_time < date('Y-m-d H:i:s')) {
                throw new Exception('兑换时间已结束');
            }
            $goods_info->has_number = ++$goods_info->has_number;
            $goods_info->save();

            $commonObj = new QrCodeController;
            $qr_code = $commonObj->getQrCode('goods_order', 'redeem_code');
            if ($qr_code === false) {
                throw new Exception('兑换失败，请重新兑换');
            }

            //生成订单信息
            $this->orderModel->order_number = get_order_id();
            $this->orderModel->user_id = $user_id;
            $this->orderModel->goods_id = $goods_id;
            $this->orderModel->account_id = $account_id;
            $this->orderModel->score = $goods_info->score;
            $this->orderModel->price = empty($goods_info->price) || $goods_info->price == "0.00" ? null : $goods_info->price;
            $this->orderModel->status = $send_way == 1 ? 1 : 3;
            $this->orderModel->is_pay = empty($goods_info->price) || $goods_info->price == "0.00" ? 2 : 1;
            $this->orderModel->payment = 1;
            $this->orderModel->redeem_code = $qr_code;
            $this->orderModel->send_way = $send_way;
            $this->orderModel->cancel_end_time = date("Y-m-d H:i:s", strtotime("+$goods_info->cancel_end_time minutes"));
            $this->orderModel->create_time = date('Y-m-d H:i:s');
            $this->orderModel->save();

            if ($send_way == 2) {
                //保存订单地址
                $addressObj = new UserAddress();
                $orderAddressObj = new GoodsOrderAddress();
                $address_info = $addressObj->find($address_id);
                $orderAddressObj->order_id = $this->orderModel->id;
                $orderAddressObj->username = $address_info->username;
                $orderAddressObj->tel = $address_info->tel;
                $orderAddressObj->province = $address_info->province;
                $orderAddressObj->city = $address_info->city;
                $orderAddressObj->district = $address_info->district;
                $orderAddressObj->street = $address_info->street;
                $orderAddressObj->address = $address_info->address;
                $orderAddressObj->create_time = date('Y-m-d H:i:s');
                $orderAddressObj->save();
            }

            if (empty($goods_info->price) || $goods_info->price == "0.00") {
                $system_id = $this->systemAdd("商品兑换成功", $user_id, $account_id, 7, $goods_id, '商品兑换成功，扣除' . $goods->score . ' 积分');

                //用户积分操作  与 系统消息
                $scoreRuleObj = new \App\Http\Controllers\ScoreRuleController();
                $scoreRuleObj->scoreGoodChange($goods_info->score, $user_id, $account_id, '商品兑换', 0, $system_id, '商品兑换成功'); //添加积分消息
            }

            DB::commit();
            return $this->returnApi(200, '兑换成功', true, [
                'order_id' => $this->orderModel->id,
                'order_number' => $this->orderModel->order_number,
                'create_time' => $this->orderModel->create_time,
                'price' => $goods_info->price,
                'postage_budget' => empty($goods_info->price) || $goods_info->price == "0.00" ? true : false //true 表示已支付，不需要支付，false 表示未支付需要支付
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, $e->getMessage());
        }
    }

    /**
     * 商品取消兑换
     * @param $token    必选
     * @param $order_id  订单id
     * @param $refund_remark  取消兑换理由  最少  5个 字
     */
    public function goodsCancelConversion()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('web_goods_cancel_conversion')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        $user_id = $this->request->user_info['id'];
        $account_id = $this->request->user_info['account_id'];
        $order_id = $this->request->order_id;
        $refund_remark = $this->request->refund_remark;

        //限制用户多次点击
        $key = md5('goods_cancel_conversion-' . $user_id . '-' . $order_id . '-' . request()->ip());
        $oldKey =  Cache::get($key); //没有缓存返回false
        if ($oldKey) {
            return $this->returnApi(201, "您操作的太频繁了，请稍后重试");
        } else {
            Cache::put($key, 1, 3);
        }

        $res = $this->orderModel->where('id', $order_id)->first();

        if (empty($res)) {
            return $this->returnApi(202, '网络错误');
        }

        if ($res->status != 1 && $res->status != 3) {
            return $this->returnApi(202, '网络错误');
        }

        //查询是否是自己的商品
        if ($res->user_id != $user_id) {
            return $this->returnApi(202, '网络错误');
        }

        if ($res->cancel_end_time < date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '此商品不允许取消');
        }

        DB::beginTransaction();
        try {
            $res = $this->orderModel->where('id', $order_id)->lockForUpdate()->first();

            //继续退款
            // if(!empty($res['price'])){
            //     $goodsPayInfoObj = new GoodsPayInfo();
            //     $goodsPayInfoObj->refund($order_id , $refund_remark);
            // }else{
            //增加一个取消的理由
            $res->refund_remark = $refund_remark;
            //   }

            $res->change_time = date('Y-m-d H:i:s');
            $res->status = 6;
            $res->save();

            $this->model->where('id', $res->goods_id)->decrement('has_number');

            //用户积分操作  与 系统消息
            $system_id = $this->systemAdd("取消商品兑换", $res->user_id, $res->account_id, 8, $res->id, '取消商品兑换成功，返还兑换商品扣除的 ' . $res->score . ' 积分');

            $scoreRuleObj = new \App\Http\Controllers\ScoreRuleController();
            $scoreRuleObj->scoreGoodReturn($res->score, $res->user_id, $res->account_id, '取消商品兑换', '取消商品兑换成功', $system_id); //添加积分消息


            DB::commit();
            return $this->returnApi(200, '取消兑换成功', true);
        } catch (\Exception $e) {
            //var_dump($e);exit;
            $msg = $e->getCode() == 2002 ? $e->getMessage() : '取消兑换失败';
            DB::rollBack();
            return $this->returnApi(202,  $msg);
        }
    }
    /**
     * 商品取消订单
     * @param $token    必选
     * @param $order_id  订单id
     * @param $refund_remark  取消订单理由  最少  5个 字
     */
    public function goodsCancelOrder()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('web_goods_cancel_order')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }
        $user_id = $this->request->user_info['id'];
        $order_id = $this->request->order_id;
        $refund_remark = $this->request->refund_remark;

        //限制用户多次点击
        $key = md5('goods_cancel_order' . $user_id . $order_id . request()->ip());
        $oldKey =  Cache::get($key); //没有缓存返回false
        if ($oldKey) {
            return $this->returnApi(201, "您操作的太频繁了，请稍后重试");
        } else {
            Cache::put($key, 1, 3);
        }

        $res = $this->orderModel->where('id', $order_id)->where('is_pay', 1)->first();
        if (empty($res)) {
            return $this->returnApi(202, '网络错误');
        }

        //查询是否是自己的商品
        if ($res->user_id != $user_id) {
            return $this->returnApi(202, '网络错误');
        }

        DB::beginTransaction();
        try {
            $res->status = 6;
            $res->is_pay = 4;
            $res->change_time = date('Y-m-d H:i:s');
            $res->refund_remark = $refund_remark;
            $res->save();

            $this->model->where('id', $res->goods_id)->decrement('has_number');


            $system_id = $this->systemAdd("取消商品兑换订单", $res->user_id, $res->account_id, 9, $order_id, '取消商品兑换订单成功');

            $scoreRuleObj = new \App\Http\Controllers\ScoreRuleController();
            $scoreRuleObj->scoreGoodReturn($res->score, $res->user_id, $res->account_id, '取消商品兑换', '取消商品兑换成功', $system_id); //添加积分消息

            DB::commit();
            return $this->returnApi(200, '取消订单成功', true);
        } catch (\Exception $e) {
            // echo $e->getMessage();die;
            DB::rollBack();
            return $this->returnApi(202, '取消订单失败');
        }
    }


    /**
     * 我的兑换列表
     *  @param token    必选
     *  @param status    状态 0全部 1 待领取  2已取走（自提） 3待发货  4已发货 （邮递）  
     *  @param page  页数 默认为 1
     *  @param limit  限制条数  默认 10 条
     */
    public function orderList()
    {
        $this->orderModel->checkOrderStatus(); //处理已过期的订单
        $this->orderModel->checkNoPayOrder(); //获取未支付的订单，判断是否过期，修改状态

        $limit = $this->request->input('limit', 10);
        $status = $this->request->input('status');
        $user_id = $this->request->user_info['id'];

        $res = $this->orderModel->from('goods_order as o')
            ->select('o.id as order_id', 'o.create_time', 'g.id as goods_id', 'o.price', 'o.score', 'g.img', 'g.name', 'g.start_time', 'g.end_time', 'status', 'is_pay', 'o.cancel_end_time', 'o.redeem_code')
            ->join('goods as g', 'g.id', '=', 'o.goods_id')
            ->where('user_id', $user_id)
            ->where(function ($query) use ($status) {
                if ($status) {
                    $query->where('status', $status);
                }
            })
            ->orderByDesc('o.create_time')
            ->paginate($limit)
            ->toArray();

        foreach ($res['data'] as $key => $val) {
            //获取状态
            $goodsOrderObj = new GoodsOrder();
            $res['data'][$key]['status'] = $goodsOrderObj->convertStatus($val['status'], $val['is_pay']);
            //是否可以取消的状态
            if (($val['status'] == 1 || $val['status'] == 3) && $val['is_pay'] == 2 && $val['cancel_end_time'] > date('Y-m-d H:i:s')) {
                $res['data'][$key]['is_can_cancel'] = true;
            } else {
                $res['data'][$key]['is_can_cancel'] = false;
            }
            $res['data'][$key]['lib_name'] = config('other.lib_name');
        }

        if ($res['data']) {
            $res = $this->disPageData($res);
            return $this->returnApi(200, '获取成功', true, $res);
        }
        return $this->returnApi(203, '暂无数据');
    }
    /**
     * 我的兑换详情
     * @param token    必选
     * @param order_id  订单id
     */
    public function orderDetail()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('web_order_detail')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $res = $this->orderModel->from('goods_order as o')
            ->select(
                'o.id as order_id',
                'o.create_time',
                'g.id as goods_id',
                'g.img',
                'g.name',
                'g.start_time',
                'g.end_time',
                'o.score',
                'o.redeem_code',
                'g.pick_end_time',
                'o.cancel_end_time',
                'status',
                'is_pay',
                'o.send_way',
                'o.tracking_number',
                'g.tel',
                'g.contacts'
            )
            ->join('goods as g', 'g.id', '=', 'o.goods_id')
            ->where('o.id', $this->request->order_id)
            ->first();

        if (empty($res)) {
            return $this->returnApi(203, '暂无数据');
        }

        //获取状态
        $goodsOrderObj = new GoodsOrder();
        $res['status'] = $goodsOrderObj->convertStatus($res['status'], $res['is_pay']);

        //是否可以取消的状态
        if (($res['status'] == 1 || $res['status'] == 3) && $res['is_pay'] == 2 && $res['cancel_end_time'] > date('Y-m-d H:i:s')) {
            $res['is_can_cancel'] = true;
        } else {
            $res['is_can_cancel'] = false;
        }

        if ($res['send_way'] == 2) {
            //获取邮递地址
            $orderAddressObj = new GoodsOrderAddress();
            $res['address_info'] = $orderAddressObj->where('order_id', $res['order_id'])->first();
        } else {
            $res['pick_address'] = GoodsAddress::select('province', 'city', 'district', 'street', 'address', 'tel', 'contacts')->first();

            //单独设置，覆盖总设置
            if ($res['tel']) {
                $res['pick_address']['tel'] = $res['tel'];
            }
            if ($res['contacts']) {
                $res['pick_address']['contacts'] = $res['contacts'];
            }
        }
        //生成二维码
        $qrCodeObj = new QrCodeController();
        $res['qr_url'] = $qrCodeObj->setQr($res['redeem_code'], false);

        $res['lib_name'] = config('other.lib_name');
        return $this->returnApi(200, '获取成功', true, $res->toArray());
    }
}
